﻿using System;
using System.Globalization;
using System.Linq;
using System.Net.Mail;
using Dexter.DataTransferObject;
using Dexter.Domain.Model;
using Dexter.Web.Mvc.ViewModel.Backoffice.Binders;
using Dexter.Web.Mvc.ViewModel.FrontEnd.Binders;

namespace Dexter.Web.Mvc.Controllers.Backoffice.Extensions {
	internal static class BinderExtensions {
		public static ConfigurationBinder ToConfigurationBinder(this SiteConfiguration configuration) {
			var cfb = new ConfigurationBinder ( );

			cfb.AdvancedFeatues = new AdvancedFeatuesBinder (  );
			cfb.AdvancedFeatues.DataCompression = configuration.AdvancedFeatues.DataCompression;
			cfb.AdvancedFeatues.StripWhiteSpace = configuration.AdvancedFeatues.StripWhiteSpace;

			cfb.AkismetApiKey = configuration.AntispamConfiguration.AkismetApiKey;
			cfb.FooterCode = configuration.FooterCode;
			cfb.HeaderCode = configuration.HeaderCode;
			cfb.BlogName = configuration.BlogName;
			cfb.CopyRight = configuration.SeoConfiguration.CopyRight;
			cfb.DayBeforeDisableComment = configuration.CommentConfiguration.DayBeforeDisableComment;
			cfb.DefaultDescription = configuration.SeoConfiguration.DefaultDescription;
			cfb.DefaultKeyWords = string.Join ( "," , configuration.SeoConfiguration.DefaultKeyWords );
			cfb.DefaultTitle = configuration.SeoConfiguration.DefaultTitle;
			cfb.EnablePingBackReceive = configuration.Tracking.EnablePingBackReceive;
			cfb.EnablePingBackSend = configuration.Tracking.EnablePingBackSend;
			cfb.EnableReferrerTracking = configuration.Tracking.EnableReferrerTracking;
			cfb.EnableTrackBackReceive = configuration.Tracking.EnableTrackBackReceive;
			cfb.EnableTrackBackSend = configuration.Tracking.EnableTrackBackSend;

			cfb.FeedBurnerUrl = configuration.FeedBurnerUrl;
			cfb.GoogleAnalyticsConfigs = new GoogleAnalyticsConfigsBinder (  );
			cfb.GoogleAnalyticsConfigs.GoogleAnalyticsPassword = configuration.GoogleAnalytics.Password;
			cfb.GoogleAnalyticsConfigs.GoogleAnalyticsProfileID = configuration.GoogleAnalytics.ProfileID;
			cfb.GoogleAnalyticsConfigs.GoogleAnalyticsUsername = configuration.GoogleAnalytics.Username;

			cfb.Language = configuration.SiteLanguage;
			cfb.ModerationType = (int)configuration.CommentConfiguration.ModerationType;
			cfb.NotificationEmailAddress = configuration.NotificationConfiguration.NotificationEmailAddress;
			cfb.NotifyNewComment = configuration.NotificationConfiguration.NotifyNewComment;
			cfb.NotifyNewTrackback = configuration.NotificationConfiguration.NotifyNewTrackback;
			
			cfb.ReCaptcha = new ReCaptchaBinder (  );
			cfb.ReCaptcha.Enable = configuration.AntispamConfiguration.ReCaptchaConfiguration.Enable;
			cfb.ReCaptcha.PrivateKey = configuration.AntispamConfiguration.ReCaptchaConfiguration.PrivateKey;
			cfb.ReCaptcha.PublicKey = configuration.AntispamConfiguration.ReCaptchaConfiguration.PublicKey;
			cfb.ReCaptcha.Theme = configuration.AntispamConfiguration.ReCaptchaConfiguration.Theme;

			cfb.SenderEmail = configuration.NotificationConfiguration.SenderEmail.Address;
			cfb.SenderEmailDisplayName = configuration.NotificationConfiguration.SenderEmail.DisplayName;

			cfb.Smtp = new SmtpBinder (  );
			cfb.Smtp.SmtpConfigurationHost = configuration.SmtpConfiguration.SmtpHost;
			cfb.Smtp.SmtpConfigurationPassword = configuration.SmtpConfiguration.Password;
			cfb.Smtp.SmtpConfigurationPort = configuration.SmtpConfiguration.Port;
			cfb.Smtp.SmtpConfigurationUsername = configuration.SmtpConfiguration.Username;
			cfb.Smtp.SmtpConfigurationUseSsl = configuration.SmtpConfiguration.UseSSL;

			cfb.ThemeName = configuration.ThemeName;
			cfb.TimeZone = configuration.TimeZone.Id;
			cfb.CultureInfo = configuration.Culture.TwoLetterISOLanguageName;

			return cfb;
		}

		public static SiteConfiguration ToSiteConfiguration ( this ConfigurationBinder configuration, SiteConfiguration instance ) {

			instance.AdvancedFeatues.DataCompression = configuration.AdvancedFeatues.DataCompression;
			instance.AdvancedFeatues.StripWhiteSpace = configuration.AdvancedFeatues.StripWhiteSpace;

			instance.FooterCode = configuration.FooterCode;
			instance.HeaderCode = configuration.HeaderCode;
			instance.BlogName = configuration.BlogName;

			instance.SeoConfiguration.CopyRight = configuration.CopyRight;
			instance.SeoConfiguration.DefaultDescription = configuration.DefaultDescription;
			instance.SeoConfiguration.DefaultKeyWords = configuration.DefaultKeyWords.Split ( new[] {','} , StringSplitOptions.RemoveEmptyEntries );
			instance.SeoConfiguration.DefaultTitle = configuration.DefaultTitle;

			instance.CommentConfiguration.DayBeforeDisableComment = configuration.DayBeforeDisableComment;
			instance.CommentConfiguration.ModerationType = (ModerationType)configuration.ModerationType;

			instance.NotificationConfiguration.NotificationEmailAddress = configuration.NotificationEmailAddress;
			instance.NotificationConfiguration.NotifyNewComment = configuration.NotifyNewComment;
			instance.NotificationConfiguration.NotifyNewTrackback = configuration.NotifyNewTrackback;
			instance.NotificationConfiguration.SenderEmail = new MailAddress ( configuration.SenderEmail, configuration.SenderEmailDisplayName );

			instance.AntispamConfiguration.AkismetApiKey = configuration.AkismetApiKey;
			instance.AntispamConfiguration.ReCaptchaConfiguration.Enable = configuration.ReCaptcha.Enable;
			instance.AntispamConfiguration.ReCaptchaConfiguration.PrivateKey = configuration.ReCaptcha.PrivateKey;
			instance.AntispamConfiguration.ReCaptchaConfiguration.PublicKey = configuration.ReCaptcha.PublicKey;
			instance.AntispamConfiguration.ReCaptchaConfiguration.Theme = configuration.ReCaptcha.Theme;

			instance.SmtpConfiguration.Password = configuration.Smtp.SmtpConfigurationPassword;
			instance.SmtpConfiguration.SmtpHost = configuration.Smtp.SmtpConfigurationHost;
			instance.SmtpConfiguration.Port = configuration.Smtp.SmtpConfigurationPort;
			instance.SmtpConfiguration.Username = configuration.Smtp.SmtpConfigurationUsername;
			instance.SmtpConfiguration.UseSSL = configuration.Smtp.SmtpConfigurationUseSsl;

			instance.Tracking.EnablePingBackReceive = configuration.EnablePingBackReceive;
			instance.Tracking.EnablePingBackSend = configuration.EnablePingBackSend;
			instance.Tracking.EnableReferrerTracking = configuration.EnableReferrerTracking;
			instance.Tracking.EnableTrackBackReceive = configuration.EnableTrackBackReceive;
			instance.Tracking.EnableTrackBackSend = configuration.EnableTrackBackSend;

			instance.FeedBurnerUrl = configuration.FeedBurnerUrl;

			instance.GoogleAnalytics.Password = configuration.GoogleAnalyticsConfigs.GoogleAnalyticsPassword;
			instance.GoogleAnalytics.ProfileID = configuration.GoogleAnalyticsConfigs.GoogleAnalyticsProfileID;
			instance.GoogleAnalytics.Username = configuration.GoogleAnalyticsConfigs.GoogleAnalyticsUsername;

			instance.SiteLanguage = configuration.Language;
			instance.Culture = CultureInfo.GetCultureInfo ( configuration.CultureInfo );


			instance.ThemeName = configuration.ThemeName;
			instance.TimeZone = TimeZoneInfo.FindSystemTimeZoneById ( configuration.TimeZone );

			return instance;
		}

		public static PostBinder ToPostBinder ( this PostDto p ) {
			PostBinder returnItem = new PostBinder {
				Abstract = p.Abstract,
				BreakOnAggregate = p.BreakOnAggregate,
				CommentEnabled = p.CommentEnabled,
				FormattedBody = p.FormattedBody,
				Id = p.Id,
				PublishDate = p.PublishDate,
				PublishHour = p.PublishDate.Hour,
				PublishMinutes = p.PublishDate.Minute,
				Slug = p.Slug,
				Tags = string.Join ( ",", p.Tags.Select ( x => x ) ),
				Title = p.Title
			};

			returnItem.Categories.AddRange ( p.Categories.Select ( x => new SimplyCategoryBinder {
				Id = x.Id,
				Name = x.Name
			} ).ToList ( ) );
			return returnItem;
		}

		public static PostBinder ToPostBinder(this Post p) {
			PostBinder returnItem = new PostBinder {
				Abstract = p.Abstract,
				BreakOnAggregate = p.BreakOnAggregate,
				CommentEnabled = p.CommentEnabled,
				FormattedBody = p.FormattedBody,
				Id = p.Id,
				Publish = p.IsPublished,
				PublishDate = p.PublishDate,
				PublishHour = p.PublishDate.Hour,
				PublishMinutes = p.PublishDate.Minute,
				Slug = p.Slug,
				Tags = string.Join ( ",", p.Tags.Select ( x => x.Name ) ),
				Title = p.Title
			};

			returnItem.Categories.AddRange ( p.Categories.Select ( x => new SimplyCategoryBinder {
				Id = x.Id,
				Name = x.Name
			} ).ToList ( ) );
			return returnItem;
		}

		public static Post ToPost(this PostBinder binder, Post instance) {
			instance.Title = binder.Title;
			instance.Abstract = binder.Abstract;
			instance.BreakOnAggregate = binder.BreakOnAggregate;
			if(binder.CommentEnabled)
				instance.EnableComment (  );
			else {
				instance.DisableComment (  );
			}

			instance.FormattedBody = binder.FormattedBody;

			instance.Id = binder.Id;
			
			if(binder.Publish)
				instance.Publish (  );
			else {
				instance.UnPublish (  );
			}

			instance.PublishDate = binder.PublishDate;
			instance.Slug = binder.Slug;

			instance.Tags.Clear (  );

			var tags = binder.Tags.Split ( new[] {','} , StringSplitOptions.RemoveEmptyEntries ).RemoveDuplicatesFromLists<string> (  );

			foreach (var tag in tags) {
				var t = TagItem.CreateNewTagItem ( tag.Trim() , instance );
				instance.Tags.Add ( t );
			}


			return instance;
		}

		public static Post ToPost ( this FastPostBinder binder, Post instance ) {
			instance.Title = binder.Title;
			instance.Abstract = binder.Abstract;
			instance.BreakOnAggregate = binder.BreakOnAggregate;
			if (binder.CommentEnabled)
				instance.EnableComment ( );
			else {
				instance.DisableComment ( );
			}

			instance.FormattedBody = binder.FormattedBody;

			instance.Id = binder.Id;

			if (binder.Publish)
				instance.Publish ( );
			else {
				instance.UnPublish ( );
			}

			instance.PublishDate = binder.PublishDate;
			instance.Slug = binder.Slug;

			var tags = binder.Tags.Split ( new[] { ',' }, StringSplitOptions.RemoveEmptyEntries ).RemoveDuplicatesFromLists<string> ( );

			foreach (var tag in tags) {
				var t = TagItem.CreateNewTagItem ( tag, instance );
				instance.Tags.Add ( t );
			}

			return instance;
		}

		public static CategoryBinder ToCategoryBinder (this Category category) {
			var binder = new CategoryBinder ( );

			binder.Name = category.Name;
			binder.Description = category.Description;

			if (category.FeedBurnerUrl != null)
				binder.FeedBurnerUrl = category.FeedBurnerUrl.ToString (  );
			
			if(category.Parent != null)
				binder.ParentId = category.Parent.Id;

			return binder;
		}

		public static PageBinder ToPageBinder ( this Page p ) {
			PageBinder returnItem = new PageBinder {
				Abstract = p.Abstract,
				FormattedBody = p.FormattedBody,
				Id = p.Id,
				Publish = p.IsPublished,
				PublishDate = p.PublishDate,
				PublishHour = p.PublishDate.Hour,
				PublishMinutes = p.PublishDate.Minute,
				Slug = p.Slug,
				Tags = string.Join ( ",", p.Tags.Select ( x => x.Name ) ),
				Title = p.Title,
				ParentPageID = p.Parent != null ? p.Parent.Id : 0
			};

			return returnItem;
		}

		public static Page ToPage ( this PageBinder binder, Page instance ) {
			instance.Title = binder.Title;
			instance.Abstract = binder.Abstract;

			instance.FormattedBody = binder.FormattedBody;

			if (binder.Publish)
				instance.Publish ( );
			else {
				instance.UnPublish ( );
			}

			instance.PublishDate = binder.PublishDate;
			instance.Slug = binder.Slug;

			var tags = binder.Tags.Split ( new[] { ',' }, StringSplitOptions.RemoveEmptyEntries ).RemoveDuplicatesFromLists<string> ( );

			instance.Tags.Clear (  );

			foreach (var tag in tags) {
				var t = TagItem.CreateNewTagItem ( tag, instance );
				instance.Tags.Add ( t );
			}

			return instance;
		}

		public static InboxMessage ToInboxMessage(this ContactBinder binder) {
			return new InboxMessage ( binder.Name , binder.Email , binder.Subject , binder.Message ) {MessageDate = DateTime.Now , IsRead = false};
		}
	}
}